exception Zero;;

let prod l =
  let rec f l =
    match l with
      | [] -> failwith "empty list"
      | [ x ] -> x
      | hd :: tl -> if hd = 0 then raise Zero else hd * f tl
  in
    try f l with Zero -> 0
;;

print_string "prod [ 1 ; 2 ; 3 ] = ";;
print_int (prod [ 1 ; 2 ; 3 ]);;
print_newline ();;

print_string "prod [ 1 ; 3 ; 0 ; 4 ] = ";;
print_int (prod [ 1 ; 3 ; 0 ; 4 ]);;
print_newline ();;

(***)

exception My_exn of string;;

let s = print_endline "compute s"; "hello" in
let exn = print_endline "compute exn"; My_exn s in
  try print_endline "before raise"; raise exn;
  with My_exn msg -> print_endline "before print"; print_endline msg;
;;

(***)

try ignore (prod [])
with
  | Failure _ -> print_endline "ok"
  | _ -> print_endline "problem"
;;

try ignore (int_of_string "toto")
with
  | Failure _ -> print_endline "ok"
  | _ -> print_endline "problem"
;;

try ignore (String.sub "toto" 10 12)
with
  | Invalid_argument _ -> print_endline "ok"
  | _ -> print_endline "problem"
;;
